package GUI;

import java.util.ArrayList;
import java.util.List;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;

import Game.GameHelper;
import Game.Level;
import GameMath.GPoint;
import GameMath.GSize;

/** GUI Map class
 * @author Aikidos
 */
public class GuiMap {
	
	/** Level */
	private Level _level;
	
	/** Map is open? */
	private boolean _open;
	
	/** Draw point size */
	private int _pointSize = 5;
	
	/** List of mark */
	private List<GPoint> _lstMarks = new ArrayList<GPoint>();
	
	/** Map mark icon */
	private Image _mapMark;
	
	/** Gui messenger */
	private GuiMessenger _guiMessenger;

	public GuiMap(Level level, GuiMessenger guiMessenger) throws SlickException {
		_level = level;
		_guiMessenger = guiMessenger;
		
		_mapMark = new Image("res/gfx/icons/map_mark.png");
	}
	
	/** Map is open? */
	public boolean isOpen() {
		return _open;
	}
	
	/** Open map */
	public void open() {
		_open = true;
	}
	
	/** Close map */
	public void close() {
		_open = false;
	}
	
	/** Adds mark to map
	 * @param coord - Mark coordinates
	 */
	public void addMark(GPoint coord) {
		boolean f = false;
		for (int i = 0; i < _lstMarks.size(); i++) {
			if (_lstMarks.get(i).x == coord.x && _lstMarks.get(i).y == coord.y) {
				f = true;
				break;
			}
		}
		
		if (!f) {
			_lstMarks.add(coord);
		}
	}
	
	/** Clear marks */
	public void clearMarks() {
		_lstMarks.clear();
	}
	
	public void update(int delta) {
		// Get input
		Input input = GameHelper.getGame().getInput();
		
		// Create/delete mark
		if (input.isKeyPressed(Input.KEY_P)) {
			GPoint coord = new GPoint();
			coord.set(_level.getObjectManager().getPlayer().getCoord());

			// Delete?
			boolean delete = false;
			for (int i = 0; i < _lstMarks.size(); i++) {
				if (_lstMarks.get(i).x == coord.x
						&& _lstMarks.get(i).y == coord.y) {
					_lstMarks.remove(i);
					delete = true;
					
					// Show message
					_guiMessenger.addMessage("[green]You[/green] deleted mark ([cyan]M[/cyan] - open map)");
				}
			}

			// Create?
			if (!delete) {
				_lstMarks.add(coord);
				
				// Show message
				_guiMessenger.addMessage("[green]You[/green] added mark ([cyan]M[/cyan] - open map)");
			}
		}
	}
	
	public void draw(Graphics g) {
		if (_open) {
			// Get map size
			GSize mapSize = _level.getMap().getSize();
		
			// Set start drawing position
			Vector2f drawPos = new Vector2f(
					(GameHelper.getGame().getWidth() / 2) - ((mapSize.width / 2) * _pointSize),
					(GameHelper.getGame().getHeight() / 2) - ((mapSize.height / 2) * _pointSize));
			
			Vector2f currDrawPos = new Vector2f(drawPos);
			
			for (int i = 0; i < _level.getMap().getSize().width; i++) {
				for (int j = 0; j < _level.getMap().getSize().height; j++) {
					// Set color by block type
					if (_level.getMap().getBlocks()[j][i].IsOpen) {
						switch (_level.getMap().getBlocks()[j][i].Type) {
						case Floor:
							g.setColor(Color.gray);
							break;
						case None:
							g.setColor(Color.black);
							break;
						case Wall:
							g.setColor(Color.white);
							break;
						}
						
						// Player?
						GPoint coord = _level.getObjectManager().getPlayer().getCoord();
						if (coord.x == j && coord.y == i)
							g.setColor(Color.green);
						
					} else
						g.setColor(Color.black);
					
					// Draw point
					g.fillRect(currDrawPos.x, currDrawPos.y, _pointSize, _pointSize);
					
					// Mark?
					for (GPoint p : _lstMarks) {
						if (p.x == j && p.y == i)
							_mapMark.draw(currDrawPos.x, currDrawPos.y);
					}
					
					currDrawPos.x += _pointSize;
				}
				
				currDrawPos.y += _pointSize;
				currDrawPos.x = drawPos.x;
			}
			
			// Draw lines
			g.setColor(Color.white);
			
			g.drawLine(drawPos.x - 1, drawPos.y - 1, 
					drawPos.x + (mapSize.width * _pointSize) + 2, 
					drawPos.y - 1);
			
			g.drawLine(drawPos.x - 1, drawPos.y - 1, 
					drawPos.x - 1, 
					drawPos.y + (mapSize.height * _pointSize) + 2);
			
			g.drawLine(drawPos.x + (mapSize.width * _pointSize) + 2, drawPos.y - 1, 
					drawPos.x + (mapSize.width * _pointSize) + 2, 
					drawPos.y + (mapSize.height * _pointSize) + 2);
			
			g.drawLine(drawPos.x - 1, drawPos.y + (mapSize.height * _pointSize) + 2, 
					drawPos.x + (mapSize.width * _pointSize) + 2, 
					drawPos.y + (mapSize.height * _pointSize) + 2);
		}
	}

}
